// GameEngine.cpp : Defines the entry point for the console application.
//

#include <Winsock2.h>
#include <iostream>
#include "stdafx.h"
#include "..\Shared\Container.h"
#include "..\Shared\Command.h"
#include "..\Shared\PluginManager.h"
#include "..\Shared\ObjectManager.h"

#pragma comment(lib,"Ws2_32.lib")

static unsigned __int64 start_tics;

unsigned __int64 __cdecl clock (
        void
        )
{
        unsigned __int64 current_tics;
        FILETIME ct;

        GetSystemTimeAsFileTime( &ct );

        current_tics = (unsigned __int64)ct.dwLowDateTime +
                       (((unsigned __int64)ct.dwHighDateTime) << 32);

        /* calculate the elapsed number of 100 nanosecond units */
        current_tics -= start_tics;

        /* return number of elapsed milliseconds */
        return (unsigned __int64)(current_tics / 10);
}

int _tmain(int argc, _TCHAR* argv[])
{
	/*m_PluginManager.Load("ExamplePlugin.dll");
	m_PluginManager.Load("NetworkPlugin.dll");
	Command MyCommand;
	MyCommand.name = "MyCommand";
	MyCommand.Arguments.Add(Value("Arg1",15));
	MyCommand.Arguments.Add(Value("Arg2","String"));
	MyCommand.Returns.Add(Value("Results",0));
	std::cout << MyCommand.ToSendableString();
	MyCommand.SetFromSendableString("Command Name:PrintObject\nArguments:1\n{\n\tName:Index Type:3 Value:NewObject0\n}\nReturns:0\n{\n}\n");
	std::cout << MyCommand.ToSendableString();
	MyCommand.Returns.Clear();
	m_ObjectManager.AddObject();
	WSADATA wsaData;
	WSAStartup(MAKEWORD(0x02, 0x00), &wsaData);
	SOCKET Socket =	socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	sockaddr_in clientService;
  clientService.sin_family = AF_INET;
  clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
  clientService.sin_port = htons(20480);
	connect(Socket, (sockaddr *) &clientService, sizeof(clientService));
	Value Temp = MyCommand.ToSendableString();
	const char *TempPtr = Temp.ToCharPtr();
	int Length = *(int*)(TempPtr-sizeof(int));
	send(Socket, TempPtr, Length, 0);
	Sleep(1000);
	char Buff[1024];
	int readed = recv(Socket, Buff, 1025, 0);
	MyCommand.SetFromSendableString(Buff);
	closesocket(Socket);

	system("PAUSE");
	return 0;
	*/

	m_PluginManager.Load("AIPlugin.dll");
	m_PluginManager.Load("ContentIOPlugin.dll");
	m_PluginManager.Load("CharCreatorPlugin.dll");
	m_PluginManager.Load("ObjectInteractionsPlugin.dll");
	m_PluginManager.Load("ExamplePlugin.dll");
	m_PluginManager.Load("MovingPlugin.dll");
	m_PluginManager.Load("NetworkPlugin.dll");

	/*Command CreateChar;
	CreateChar.name = "StartCharCreation";
	m_PluginManager.HandleCommand(CreateChar);
	CreateChar.name = "AutoAssignPoints";
	m_PluginManager.HandleCommand(CreateChar);
	CreateChar.name = "InstantiateChar";
	CreateChar.Arguments.Add("True");
	m_PluginManager.HandleCommand(CreateChar);
	Value &Name = m_ObjectManager[0].GetBaseAttribute("Name");
	Name = "Test Object";

	m_ObjectManager.AddObject();
	Object &Sword = m_ObjectManager[m_ObjectManager.GetSize()-1];
	Value &SwordName = Sword.GetBaseAttribute("Name");
	SwordName = "Sword";
	m_ObjectManager.AddChildToObject(Name, SwordName);
	m_ObjectManager.AddAttributeToObject(SwordName,Value("EquipLocation","RHand"));

	Command Equip;
	Equip.name = "Equip";
	Equip.Arguments.Add(Name);
	Equip.Arguments.Add(SwordName);

	m_PluginManager.HandleCommand(Equip);

	Command TestSaveIO;
	TestSaveIO.name = "SaveObject";
	TestSaveIO.Arguments.Add("TestObject.txt");
	TestSaveIO.Arguments.Add("Test Object");
	TestSaveIO.Arguments.Add("File OverWrite");
	m_PluginManager.HandleCommand(TestSaveIO);

	m_ObjectManager.Clear();*/

	Command TestLoadIO;
	TestLoadIO.name = "LoadObject";
	TestLoadIO.Arguments.Add("TestObject.txt");
//	TestLoadIO.Arguments.Add("Test Object");
	m_PluginManager.HandleCommand(TestLoadIO);

	Command MyCommand;
	MyCommand.SetFromSendableString("Command Name:PrintObject\nArguments:1\n{\n\tName:Index Type:3 Value:Test Object\n}\nReturns:2\n{\n\tName:Results Type:1 Value:0\n\tName:Error Type:3 Value:Not Found\n}\n");
	MyCommand.Returns.Clear();
	
	WSADATA wsaData;
	WSAStartup(MAKEWORD(0x02, 0x00), &wsaData);
	SOCKET Socket =	socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	sockaddr_in clientService;
  clientService.sin_family = AF_INET;
  clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
  clientService.sin_port = htons(20480);
	connect(Socket, (sockaddr *) &clientService, sizeof(clientService));
	Value Temp = MyCommand.ToSendableString();
	const char *TempPtr = Temp.ToCharPtr();
	int Length = *(int*)(TempPtr-sizeof(int));
	send(Socket, TempPtr, Length, 0);
	Sleep(0);
	char Buff[1024];
	int readed = recv(Socket, Buff, 1024, 0);
	Buff[readed < 1023 ? readed : 1023] = 0;
	MyCommand.SetFromSendableString(Buff);
	std::cout << MyCommand.ToSendableString() << std::endl;

	Command SendToSocket;
	SendToSocket.name = "SendToSocket";
	SendToSocket.Arguments.Add(0);
	SendToSocket.Arguments.Add("Test String.\n");
	m_PluginManager.HandleCommand(SendToSocket);

	readed = recv(Socket, Buff, 1024, 0);
	Buff[readed < 1023 ? readed : 1023] = 0;
	std::cout << Buff;





	closesocket(Socket);
	

	/*Command PrintObject;
	PrintObject.name = "PrintObject";
	PrintObject.Arguments.Add("Test Object");
	PrintObject.Arguments.Add("Equipped");
	PrintObject.Arguments.Add("Sword");
	m_PluginManager.HandleCommand(PrintObject);
*/
	system("PAUSE");
	return 0;
}